#include "StdAfx.h"
#include "HCircuitView.h"
#include "HIOManager.h"
#include "HBaseModel.h"
#include "HConstantFrameRate.h"


HCircuitView::HCircuitView(	HBaseModel *model,
							const char * alias,	
							const char * driver_type,
							const char * instance_name,
							void * window_handle,
							void * colormap,
							void * clip_override,
							void * window_handle_2,
							const char * driver_path)
:HBaseView(model,alias,driver_type,instance_name,window_handle,colormap,clip_override,window_handle_2,driver_path)
{

}


HCircuitView::~HCircuitView(void)
{

}


HFileOutputResult HCircuitView::FileOutput(const wchar_t * FileName, HOutputHandler * handler, HOutputHandlerOptions * options)
{
	HOutputHandlerOptions defaultOptions;

	if(!handler) return OutputNotHandled;
	if(!FileName) return OutputBadFileName;
	if(!options) {
		options = &defaultOptions;
		options->WindowWidth(6.4f);
		options->WindowHeight(4.8f);
		options->ImageDpi(100);
	}

	HFileOutputResult result = OutputNotHandled;

	options->View(this);
	HCamera camera;

	if(handler->GetOutputStyle() == HOutputHandlerStyleModel)
	{

		if (!options->m_pCamera)
		{
			GetCamera(&camera);
			options->m_pCamera = &camera;
		}

		//TODO we should extend this option to other Output styles
		if (options->m_Key == INVALID_KEY)
			options->m_Key = GetModel()->GetModelKey();

		result = handler->FileOutputByKey(FileName, options->m_Key, options);
	}
	
	else if(handler->GetOutputStyle() == HOutputHandlerStyleImage) {

		FramerateMode mode = m_FramerateMode;
		int steps = 20;//SimpList ? SimpList[1]->GetMaxSimpLevel() : 20;
		bool useLod = false;//SimpList ? ((HFrExtent *)SimpList[1])->GetUseLod() : false;
		float target = GetMaximumUpdateTime();
		int threshold = GetCullingThreshold();

		SetFramerateMode(FramerateOff);

		if(options->m_Window_Width == 0 || options->m_Window_Height == 0 || options->m_Image_Dpi == 0) {

			result = OutputBadOptions;
		}else{

			char hsra_options[MVO_BUFFER_SIZE];
			char hlr_options[MVO_BUFFER_SIZE];
			char current_hsra[MVO_BUFFER_SIZE];
			char color[MVO_BUFFER_SIZE];
			char anti_aliasing[MVO_BUFFER_SIZE];
			char windowPattern[MVO_BUFFER_SIZE];

			/* first find out the relevant options associated with the view */
			HC_Open_Segment_By_Key(GetViewKey());
			HC_Show_One_Net_Rendering_Optio("hidden surface removal algorithm", current_hsra);

			if( HC_Show_Existence("color"))
				HC_Show_Color(color);
			else
			{
				HPoint topColor;
				HPoint bottomColor;

				GetWindowColor	(topColor,bottomColor);
				HCLOCALE(sprintf(color, "windows=(r=%f g=%f b=%f), window contrast = (r=%f g=%f b=%f)", topColor.x, topColor.y, topColor.z, bottomColor.x, bottomColor.y, bottomColor.z));
			}

			HC_Show_Net_Window_Pattern(windowPattern);

			HRenderMode rndrmode = GetRenderMode();
			if (rndrmode == HRenderHiddenLine || rndrmode == HRenderHiddenLineFast || rndrmode == HRenderBRepHiddenLine) 
			{
				HC_Show_One_Net_Rendering_Optio("hidden line removal options", hlr_options);
				sprintf(hsra_options, "hsra = hidden line, hidden line removal options = (%s)", hlr_options);
			}else{
				if (options->HSRAOptions())
					sprintf(hsra_options, "hsra = %s", options->HSRAOptions());
				else if (handler->GetOutputDefaultHSRA())
					sprintf(hsra_options, "hsra = %s", handler->GetOutputDefaultHSRA());
				else
					sprintf(hsra_options, "hsra = szb, technology = software frame buffer");
			}
			HC_Show_One_Net_Rendering_Option("anti-aliasing", anti_aliasing);
			HC_Close_Segment();

			char image_segment[MVO_SEGMENT_PATHNAME_BUFFER];
			HBestImageDriver driver_segment(GetDriverType());

			sprintf(image_segment,"?driver/null/hbaseview_%p", (void*)this);


			int x_size=(int)(options->m_Window_Width * options->m_Image_Dpi + 0.5f);
			int y_size=(int)(options->m_Window_Height * options->m_Image_Dpi + 0.5f);

			// prepare image for rendering
			HC_Open_Segment(image_segment);
			HC_KEY image_key = HC_KInsert_Image (0.0, 0.0, 0.0, "rgba", x_size, y_size, 0);
			HC_Close_Segment ();

			// prepare data to render
			HC_Open_Segment(driver_segment);
			//HC_Set_Rendering_Options("attribute lock = (color = (window))");
			//HC_Set_Color_By_Value("windows", "RGB", m_WindowColor.x, m_WindowColor.y, m_WindowColor.z);
			HC_Set_Window_Frame("off");
			HC_Set_Rendering_Options(hsra_options);
			//HC_Set_Rendering_Options("hsra = szb");

			HC_Set_Rendering_Options(
				H_FORMAT_TEXT("anti-alias = (%s), %s",
				anti_aliasing,
				options->m_ForceGrayscale ? "force grayscale = on" : "force grayscale = off"));

			H_FORMAT_TEXT drvopt(
				"use window id = (image key = %s%p),"
				"subscreen = (-1, 1, -1, 1),"
				"isolated,no gamma correction,"
				"physical size = (%g, %g),"
				"hardcopy resolution = %d",
				H_EXTRA_POINTER_FORMAT,
				(void*)image_key,
				options->WindowWidth()*2.54f,
				options->WindowHeight()*2.54f,
				options->ImageDpi());

			HC_Set_Driver_Options (drvopt);

			HC_Set_Color(color);

			HC_Set_Window_Pattern(windowPattern);

			HC_Include_Segment_By_Key (GetSceneKey());
			HC_Close_Segment ();

			bool fgs_scene = false;
			bool fgs_axis = false;
			if(options->m_ForceGrayscale){
				HC_Open_Segment_By_Key(options->m_pHBaseView->GetSceneKey());{
					fgs_scene = HUtility::PushAttribute("rendering options");
					HC_Set_Rendering_Options("force grayscale = on");
					HC_Open_Segment("axis");{
						fgs_axis = HUtility::PushAttribute("rendering options");
						HC_Set_Rendering_Options("force grayscale = on");
					}HC_Close_Segment();	
				}HC_Close_Segment();
			}

			HC_Update_One_Display(driver_segment);

			/* Restore the scene to the way it was before twopassprinting */
			if(options->m_ForceGrayscale){
				HC_Open_Segment_By_Key(options->m_pHBaseView->GetSceneKey());{
					if(fgs_scene) HUtility::PopAttribute("rendering options");
					else HC_UnSet_One_Rendering_Option("force grayscale");
					HC_Open_Segment("axis");{
						if(fgs_axis) HUtility::PopAttribute("rendering options");
						else HC_UnSet_One_Rendering_Option("force grayscale");
					}HC_Close_Segment();
				}HC_Close_Segment();
			}

			result = handler->FileOutputFromImageKey(FileName, image_key, options);

			HC_Delete_Segment(driver_segment);
			HC_Delete_Segment(image_segment);
		}

		SetFramerateMode(mode,target,threshold,useLod,steps);
	}
	else if(handler->GetOutputStyle() == HOutputHandlerStyleHardcopy) {

		char hsra_options[MVO_BUFFER_SIZE];
		char hlr_options[MVO_BUFFER_SIZE];
		char current_hsra[MVO_BUFFER_SIZE];

		/* first find out the relevant options associated with the view */
		HC_Open_Segment_By_Key(GetViewKey());
		HC_Show_One_Net_Rendering_Optio("hidden surface removal algorithm", current_hsra);

		HRenderMode rndrmode = GetRenderMode();
		if (rndrmode == HRenderHiddenLine || rndrmode == HRenderHiddenLineFast || rndrmode == HRenderBRepHiddenLine) 
		{
			HC_Show_One_Net_Rendering_Optio("hidden line removal options", hlr_options);
			sprintf(hsra_options, "hsra = hidden line, hidden line removal options = (%s)", hlr_options);
		}else{

			if(handler->GetOutputDefaultHSRA())
				sprintf(hsra_options, "hsra = %s", handler->GetOutputDefaultHSRA());
			else
				sprintf(hsra_options, "hsra = painters");
		}
		HC_Close_Segment();

		options->HSRAOptions(hsra_options);

		HPoint windowColor;
		GetWindowColor(windowColor);
		options->WindowColor(&windowColor);

		result = handler->FileOutputByKey(FileName, GetSceneKey(), options);

	}
	else if(handler->GetOutputStyle() == HOutputHandlerStyleHTML) {

		HOutputHandler * extra_handler = HDB::GetHIOManager()->GetOutputHandler("hsf");

		if(!extra_handler) return OutputNotHandled;

		// html is HOutputHandlerStyleModel
		result = handler->FileOutputByKey(FileName, GetModel()->GetModelKey(), options);

		if(result == OutputOK) {

			// now create a HSF file
			wchar_t hsf_name[MVO_BUFFER_SIZE];
			size_t n = wcslen(FileName);
			while (n && FileName[n] != L'.') n--;
			wcsncpy(hsf_name, FileName, n);
			hsf_name[n] = L'\0';
			wcscat(hsf_name, L".hsf");

			// hsf is HOutputHandlerStyleModel
			result =  extra_handler->FileOutputByKey(hsf_name, GetModel()->GetModelKey(), options);
		}
	}

	return result;
}
